/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package skyproc;

import java.util.Objects;

/**
 *
 * @author Justin Swanson
 */
public class FACT extends MajorRecordNamed {

    static Type[] types = {Type.FACT};
    SubList<SubData> XNAMs = new SubList<SubData>(new SubData(Type.XNAM));
    SubData DATA = new SubData(Type.DATA);
    SubForm JAIL = new SubForm(Type.JAIL);
    SubForm WAIT = new SubForm(Type.WAIT);
    SubForm STOL = new SubForm(Type.STOL);
    SubForm PLCN = new SubForm(Type.PLCN);
    SubForm CRGR = new SubForm(Type.CRGR);
    SubForm JOUT = new SubForm(Type.JOUT);
    SubData CRVA = new SubData(Type.CRVA);
    SubForm VEND = new SubForm(Type.VEND);
    SubForm VENC = new SubForm(Type.VENC);
    SubData VENV = new SubData(Type.VENV);
    SubList<FACT.Rank> ranks = new SubList<FACT.Rank>(new FACT.Rank());
    SubInt CITC = new SubInt(Type.CITC);
    SubString CIS2 = new SubString(Type.CIS2, true);
    SubData CTDA = new SubData(Type.CTDA);
    SubData PLVD = new SubData(Type.PLVD);

    FACT() {
	super();

	subRecords.add(XNAMs);
	subRecords.add(DATA);
	subRecords.add(JAIL);
	subRecords.add(WAIT);
	subRecords.add(STOL);
	subRecords.add(PLCN);
	subRecords.add(CRGR);
	subRecords.add(JOUT);
	subRecords.add(CRVA);
	subRecords.add(ranks);
	subRecords.add(VEND);
	subRecords.add(VENC);
	subRecords.add(VENV);
	subRecords.add(PLVD);
	subRecords.add(CITC);
	subRecords.add(CTDA);
	subRecords.add(CIS2);
    }

    @Override
    Type[] getTypes() {
	return types;
    }

    @Override
    Record getNew() {
	return new FACT();
    }
    
    @Override
    public boolean equals(Object obj) {
        if (obj == null) {
            return false;
        }
        if (getClass() != obj.getClass()) {
            return false;
        }
        final FACT other = (FACT) obj;
        if (!Objects.equals(this.XNAMs, other.XNAMs)) {
            return false;
        }
        if (!Objects.equals(this.DATA, other.DATA)) {
            return false;
        }
        if (!Objects.equals(this.JAIL, other.JAIL)) {
            return false;
        }
        if (!Objects.equals(this.WAIT, other.WAIT)) {
            return false;
        }
        if (!Objects.equals(this.STOL, other.STOL)) {
            return false;
        }
        if (!Objects.equals(this.PLCN, other.PLCN)) {
            return false;
        }
        if (!Objects.equals(this.CRGR, other.CRGR)) {
            return false;
        }
        if (!Objects.equals(this.JOUT, other.JOUT)) {
            return false;
        }
        if (!Objects.equals(this.CRVA, other.CRVA)) {
            return false;
        }
        if (!Objects.equals(this.VEND, other.VEND)) {
            return false;
        }
        if (!Objects.equals(this.VENC, other.VENC)) {
            return false;
        }
        if (!Objects.equals(this.VENV, other.VENV)) {
            return false;
        }
        if (!Objects.equals(this.ranks, other.ranks)) {
            return false;
        }
        if (!Objects.equals(this.CITC, other.CITC)) {
            return false;
        }
        if (!Objects.equals(this.CIS2, other.CIS2)) {
            return false;
        }
        if (!Objects.equals(this.CTDA, other.CTDA)) {
            return false;
        }
        if (!Objects.equals(this.PLVD, other.PLVD)) {
            return false;
        }
        return true;
    }

    @Override
    public int hashCode() {
        int hash = 7;
        hash = 97 * hash + Objects.hashCode(this.XNAMs);
        hash = 97 * hash + Objects.hashCode(this.DATA);
        hash = 97 * hash + Objects.hashCode(this.JAIL);
        hash = 97 * hash + Objects.hashCode(this.WAIT);
        hash = 97 * hash + Objects.hashCode(this.STOL);
        hash = 97 * hash + Objects.hashCode(this.PLCN);
        hash = 97 * hash + Objects.hashCode(this.CRGR);
        hash = 97 * hash + Objects.hashCode(this.JOUT);
        hash = 97 * hash + Objects.hashCode(this.CRVA);
        hash = 97 * hash + Objects.hashCode(this.VEND);
        hash = 97 * hash + Objects.hashCode(this.VENC);
        hash = 97 * hash + Objects.hashCode(this.VENV);
        hash = 97 * hash + Objects.hashCode(this.ranks);
        hash = 97 * hash + Objects.hashCode(this.CITC);
        hash = 97 * hash + Objects.hashCode(this.CIS2);
        hash = 97 * hash + Objects.hashCode(this.CTDA);
        hash = 97 * hash + Objects.hashCode(this.PLVD);
        return hash;
    }
    
    @Override
    public MajorRecord merge(MajorRecord no, MajorRecord bo) {
        super.merge(no, bo);
        FACT r = this;
        if (!(no == null && bo == null && (no instanceof FACT) && (bo instanceof FACT))) {
            final FACT nr = (FACT) no;
            final FACT br = (FACT) bo;
            SubRecords sList = r.subRecords;
            SubRecords nsList = nr.subRecords;
            SubRecords bsList = br.subRecords;
            for (SubRecord s : sList) {
                s.merge(nsList.get(s.type[0]), bsList.get(s.type[0]));
            }
        }
        return r;
    }

    static class Rank extends SubShell {

	SubInt RNAM = new SubInt(Type.RNAM);
	SubStringPointer MNAM = new SubStringPointer(Type.MNAM, SubStringPointer.Files.STRINGS);
	SubData FNAM = new SubData(Type.FNAM);

	static Type[] types = {Type.RNAM, Type.MNAM, Type.FNAM};

	Rank() {
	    super(types);
	    subRecords.add(RNAM);
	    subRecords.add(MNAM);
	    subRecords.add(FNAM);
	}

	@Override
	Boolean isValid() {
	    return RNAM.isValid()
		    || MNAM.isValid()
		    || FNAM.isValid();
	}

	@Override
	SubRecord getNew(Type type) {
	    return new FACT.Rank();
	}

        @Override
        public boolean equals(Object obj) {
            if (obj == null) {
                return false;
            }
            if (getClass() != obj.getClass()) {
                return false;
            }
            final Rank other = (Rank) obj;
            if (!Objects.equals(this.RNAM, other.RNAM)) {
                return false;
            }
            if (!Objects.equals(this.MNAM, other.MNAM)) {
                return false;
            }
            if (!Objects.equals(this.FNAM, other.FNAM)) {
                return false;
            }
            return true;
        }

        @Override
        public int hashCode() {
            int hash = 3;
            hash = 83 * hash + Objects.hashCode(this.RNAM);
            hash = 83 * hash + Objects.hashCode(this.MNAM);
            hash = 83 * hash + Objects.hashCode(this.FNAM);
            return hash;
        }
    }
}
